<template>
  <div
    class="rectangle"
    :class="{ selected: isSelected }"
    :style="rectangleStyle"
    @mousedown="onMouseDown"
    @mouseup="onMouseUp"
  >
    <div class="rectangle-container">
      <!-- Add content for your rectangle -->
      <div
        v-if="isSelected"
        class="resize-handle top-left"
        @mousedown="onResizeMouseDown('top-left')"
      ></div>
      <div
        v-if="isSelected"
        class="resize-handle top-right"
        @mousedown="onResizeMouseDown('top-right')"
      ></div>
      <div
        v-if="isSelected"
        class="resize-handle bottom-left"
        @mousedown="onResizeMouseDown('bottom-left')"
      ></div>
      <div
        v-if="isSelected"
        class="resize-handle bottom-right"
        @mousedown="onResizeMouseDown('bottom-right')"
      ></div>
      <div
        v-if="isSelected"
        class="resize-handle top"
        @mousedown="onResizeMouseDown('top')"
      ></div>
      <div
        v-if="isSelected"
        class="resize-handle bottom"
        @mousedown="onResizeMouseDown('bottom')"
      ></div>
      <div
        v-if="isSelected"
        class="resize-handle left"
        @mousedown="onResizeMouseDown('left')"
      ></div>
      <div
        v-if="isSelected"
        class="resize-handle right"
        @mousedown="onResizeMouseDown('right')"
      ></div>
    </div>
  </div>
</template>

<script>
import { debounce } from "lodash";
export default {
  props: {
    initialX: { type: Number, default: 0 },
    initialY: { type: Number, default: 0 },
    initialWidth: { type: Number, default: 200 },
    initialHeight: { type: Number, default: 100 },
    isSelected: { type: Boolean, default: false },
  },
  data() {
    return {
      isResizing: false,
      resizeHandle: "", // 用于标记选中的调节大小手柄
      isDragging: false,
      startX: 0,
      startY: 0,
      offsetX: 0,
      offsetY: 0,
      startWidth: 0,
      startHeight: 0,
      x: this.initialX,
      y: this.initialY,
      width: this.initialWidth,
      height: this.initialHeight,
      animationFrameId: null,
    };
  },
  computed: {
    rectangleStyle() {
      // Use CSS translate property for hardware acceleration
      return {
        left: `${this.x}px`,
        top: `${this.y}px`,
        width: `${this.width}px`,
        height: `${this.height}px`,
      };
    },
  },
  methods: {
    onMouseDown(event) {
      console.log("onMouseDown");
      this.$emit("mousedown", event);

      const rect = this.$el.getBoundingClientRect();
      this.offsetX = event.clientX - rect.left;
      this.offsetY = event.clientY - rect.top;

      console.log("resize-handle");
      console.log(event.target.classList.contains("resize-handle"));
      if (event.target.classList.contains("resize-handle")) {
        this.isResizing = true;
      } else {
        this.isDragging = true;
      }

      this.startX = event.clientX;
      this.startY = event.clientY;
      this.startWidth = this.width;
      this.startHeight = this.height;

      document.addEventListener("mousemove", this.onMouseMove);
      document.addEventListener("mouseup", this.onMouseUp);
    },
    onMouseMove(event) {
      if (this.isDragging) {
        // const deltaX = event.clientX - this.startX;
        // const deltaY = event.clientY - this.startY;
        // this.x = this.startX + deltaX;
        // this.y = this.startY + deltaY;
        // Calculate the new position based on the mouse offset
        const newX = event.clientX - this.offsetX;
        const newY = event.clientY - this.offsetY - this.offsetY;

        // Ensure that the rectangle stays within its container boundaries (optional)
        const containerRect = this.$el.parentNode.getBoundingClientRect();
        this.x = Math.min(Math.max(newX, 0), containerRect.width - this.width);
        this.y = Math.min(
          Math.max(newY, 0),
          containerRect.height - this.height
        );
      } else if (this.isResizing) {
        const deltaX = event.clientX - this.startX;
        const deltaY = event.clientY - this.startY;
        switch (this.resizeHandle) {
          case "top-left":
            this.x = this.startX + deltaX;
            this.y = this.startY + deltaY;
            this.width = this.startWidth - deltaX;
            this.height = this.startHeight - deltaY;
            break;
          case "top-right":
            this.y = this.startY + deltaY;
            this.width = this.startWidth + deltaX;
            this.height = this.startHeight - deltaY;
            break;
          case "bottom-left":
            this.x = this.startX + deltaX;
            this.width = this.startWidth - deltaX;
            this.height = this.startHeight + deltaY;
            break;
          case "bottom-right":
            this.width = this.startWidth + deltaX;
            this.height = this.startHeight + deltaY;
            break;
          case "top":
            this.y = this.startY + deltaY;
            this.height = this.startHeight - deltaY;
            break;
          case "bottom":
            this.height = this.startHeight + deltaY;
            break;
          case "left":
            this.x = this.startX + deltaX;
            this.width = this.startWidth - deltaX;
            break;
          case "right":
            this.width = this.startWidth + deltaX;
            break;
          default:
            break;
        }
      }
    },
    onMouseUp() {
      this.isDragging = false; // Stop dragging when mouse is released
      this.isResizing = false;
      // document.removeEventListener("mousemove", this.onMouseMove);
      document.removeEventListener("mousemove", this.debouncedOnMouseMove);
      document.removeEventListener("mouseup", this.onMouseUp);
    },
    onResizeMouseDown(event) {
      this.isResizing = true;
      this.resizeHandle = event;
      // this.startX = event.clientX;
      // this.startY = event.clientY;
      this.offsetX = event.clientX;
      this.offsetY = event.clientY;
      this.startWidth = this.width;
      this.startHeight = this.height;
      // document.addEventListener("mousemove", this.onMouseMove);
      document.addEventListener("mousemove", this.debouncedOnMouseMove);
      document.addEventListener("mouseup", this.onMouseUp);
    },
    // Add debounced version of onMouseMove
    debouncedOnMouseMove: debounce(function (event) {
      this.onMouseMove(event);
    }, 100),
  },
};
</script>

<style scoped>
/* 省略样式代码，同上 */
.rectangle {
  position: absolute;
  background-color: #f0f0f0;
  border: 1px dashed #ccc;
  box-sizing: border-box;
}

.rectangle-container {
  position: relative;
  height: 100%;
  width: 100%;
  cursor: move;
}

.resize-handle {
  position: absolute;
  width: 10px;
  height: 10px;
  bottom: 0;
  right: 0;
  cursor: se-resize;
  background-color: #007bff;
}

.top-left {
  top: 0;
  left: 0;
  cursor: nw-resize;
}

.top-right {
  top: 0;
  right: 0;
  cursor: ne-resize;
}

.bottom-left {
  bottom: 0;
  left: 0;
  cursor: sw-resize;
}

.bottom-right {
  bottom: 0;
  right: 0;
  cursor: se-resize;
}

.top {
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  cursor: n-resize;
}

.bottom {
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  cursor: s-resize;
}

.left {
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  cursor: w-resize;
}

.right {
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  cursor: e-resize;
}

.rectangle.selected {
  border: 1px dashed #007bff;
}
</style>
